﻿using InputTool;
using KCommon;
using KeyboardArg;
using LogLib;
using SelectionKeyBoard;
using SoftKeyBoard;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Forms;

namespace KeyboardFactory
{
    public class Keyboards
    {
        #region static field and functions
        private static object _lock = new object();
        protected static Keyboards _instance;
        public static Keyboards Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock)
                    {
                        if (_instance == null)
                        {
                            _instance = new Keyboards();
                        }
                    }
                }
                return _instance;
            }
        }
        #endregion

        public event KeyboardClosedEventHandler KeyboardClosed;
        protected void OnKeyboardClosed(KeyBoardArgs args)
        {
            if (KeyboardClosed != null)
            {
                KeyboardClosed(this, new KeyboardClosedEventArgs(args));
            }
        }

        private FormInputTool _inputTool = null;

        private FormInputID _inputID = null;

        private FormInputPhoneNumber _inputPhone = null;

        private MainWindow _selectKeyBoard = null;

        //private FormInputWord FormInputWord = null;

        private FormKeyInputing _letterKeyBoard = null;
        
        private FormInputPassportNumber _inputPassport = null;

        private Dictionary<Form, bool> AllWinForms = new Dictionary<Form, bool>();

        private Dictionary<Window, bool> AllWpfForms = new Dictionary<Window, bool>();

        private KeyBoardArgs CurrentInputArgs = null;

        private string CalendarAppPath = "";

        /// <summary>
        /// 指示当前的软键盘是否处于被激活状态
        /// </summary>
        private bool _isKeyboardActived = false;

        private Keyboards()
        {
            CreatAllKindOfKeyBoard();
        }

        public string GetAssemblyDirectory()
        {
            Assembly ass = this.GetType().Assembly;
            string directory = Path.GetDirectoryName(ass.CodeBase);
            if (directory.StartsWith("file:\\"))
            {
                directory = directory.Substring(6);
            }
            return directory;
        }

        private void CreatAllKindOfKeyBoard()
        {
            string dir = GetAssemblyDirectory();
            CalendarAppPath = Path.Combine(dir, "CalendarBoard.exe");

            _inputTool = new FormInputTool();
            _inputTool.Hidden += OnKeyboardHidden;
            _inputTool.FormClosed += OnKeyboardClosed;

            _selectKeyBoard = new MainWindow();
            _selectKeyBoard.Hidden += OnKeyboardHidden;
            _selectKeyBoard.Closed += OnKeyboardClosed;

            _inputID = new FormInputID();
            _inputID.Hidden += OnKeyboardHidden;
            _inputID.FormClosed += OnKeyboardClosed;

            _inputPhone = new FormInputPhoneNumber();
            _inputPhone.Hidden += OnKeyboardHidden;
            _inputPhone.FormClosed += OnKeyboardClosed;

            _inputPassport = new FormInputPassportNumber();
            _inputPassport.Hidden += OnKeyboardHidden;
            _inputPassport.FormClosed += OnKeyboardClosed;

            //FormInputWord = new FormInputWord();
            //FormInputWord.Hidden += OnKeyboardHidden;
            //FormInputWord.FormClosed += OnKeyboardClosed;

            _letterKeyBoard = new FormKeyInputing();
            _letterKeyBoard.Hidden += OnKeyboardHidden;
            _letterKeyBoard.FormClosed += OnKeyboardClosed;

            AllWpfForms.Add(_selectKeyBoard, false);
            AllWinForms.Add(_inputTool, false);
            AllWinForms.Add(_inputID, false);
            AllWinForms.Add(_inputPhone, false);
            AllWinForms.Add(_inputPassport, false);
            AllWinForms.Add(_letterKeyBoard, false);
            //AllWinForms.Add(FormInputWord, false);
            //AllWinForms.Add(FormKeyboard, false);
            //AllWinForms.Add(FormPlateColor, false);
        }

        private void OnKeyboardHidden(object sender, EventArgs e)
        {          
            if (sender is FormInputTool)
            {
                KeyBoardArgs args = _inputTool.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is FormInputPhoneNumber)
            {
                KeyBoardArgs args = _inputPhone.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is FormInputPassportNumber)
            {
                KeyBoardArgs args = _inputPassport.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is FormInputID)
            {
                KeyBoardArgs args = _inputID.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is MainWindow)
            {
                KeyBoardArgs args = _selectKeyBoard.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is FormKeyInputing)
            {
                KeyBoardArgs args = _letterKeyBoard.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            //else if (sender is FormPlateColor)
            //{
            //    KeyBoardArgs args = FormPlateColor.KeyboardArgs;
            //    OnKeyboardClosed(args);
            //}

            _isKeyboardActived = false;
        }

        private void OnKeyboardClosed(object sender, EventArgs e)
        {
            if (sender is FormInputTool)
            {
                KeyBoardArgs args = _inputTool.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is FormInputPhoneNumber)
            {
                KeyBoardArgs args = _inputPhone.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is FormInputPassportNumber)
            {
                KeyBoardArgs args = _inputPassport.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is FormInputID)
            {
                KeyBoardArgs args = _inputID.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is MainWindow)
            {
                KeyBoardArgs args = _selectKeyBoard.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            else if (sender is FormKeyInputing)
            {
                KeyBoardArgs args = _letterKeyBoard.KeyboardArgs;
                OnKeyboardClosed(args);
            }
            //else if (sender is FormPlateColor)
            //{
            //    KeyBoardArgs args = FormPlateColor.KeyboardArgs;
            //    OnKeyboardClosed(args);
            //}
            _isKeyboardActived = false;
        }

        private void OnWinFormShown(Form form)
        {
            if (!_isKeyboardActived)
            {
                return;
            }
            var allForms = AllWinForms.Keys;
            foreach (var key in allForms)
            {
                if (form != key)
                {
                    key.Hide();
                }
            }
            var allWpfForms = AllWpfForms.Keys;
            foreach (var key in allWpfForms)
            {
                key.Hide();
            }
            AllWinForms[form] = true;
        }

        private void OnWpfFormShown(Window window)
        {
            if (!_isKeyboardActived)
            {
                return;
            }
            var allForms = AllWinForms.Keys;
            foreach (var key in allForms)
            {
                key.Hide();
            }
            AllWpfForms[window] = true;
        }

        private void OnCalendarShown()
        {
            if (!_isKeyboardActived)
            {
                return;
            }
            var allForms = AllWinForms.Keys;
            foreach (var key in allForms)
            {
                key.Hide();
            }
            var allWpfForms = AllWpfForms.Keys;
            foreach (var key in allWpfForms)
            {
                key.Hide();
            }
        }

        private void FindActivatedKeyboard()
        {
            var allForms = AllWinForms.Keys;
            foreach (var key in allForms)
            {
                if (key.Visible)
                {
                    Log.WriteAsync($"键盘已经是激活状态:{key.Name}");
                }
            }
            var allWpfForms = AllWpfForms.Keys;
            foreach (var key in allWpfForms)
            {
                if (key.IsVisible)
                {
                    Log.WriteAsync($"键盘已经是激活状态:{key.Name}");
                }
            }
        }

        private void ShowCalendarWnd(KeyBoardArgs args)
        {
            var pro = Process.GetProcesses().Where(t => t.ProcessName.Contains("CalendarBoard")).FirstOrDefault();
            if (pro != null)
            {
                try
                {
                    pro.Kill();
                }
                catch
                {

                }
            }

            Process process = new Process();
            process.StartInfo.FileName = CalendarAppPath;
            string parm = JsonHandler.ConvertToJsonString(args).Replace('"', '@');
            process.StartInfo.Arguments = parm;
            process.Start();
            _isKeyboardActived = true;
        }

        public void OnKeyboardPopup(object sender, KeyboardPopupEventArgs e,System.Drawing.Rectangle screenRect)
        {
            KeyBoardArgs args = e.Args;
            if (args == null)
            {
                return;
            }
            if (_isKeyboardActived)
            {
                FindActivatedKeyboard();
            }
            CurrentInputArgs = args;
            args.ScreenWorkArea = screenRect;
            if (args.DictionaryFileName.StartsWith("Date")) // 使用日期选择键盘
            {
                OnCalendarShown();
                args.SenderHandle = Process.GetCurrentProcess().MainWindowHandle;                
                ShowCalendarWnd(args);
            }
            else if (args.DictionaryFileName.Equals("Number")
                || args.DictionaryFileName.Equals("IDCard"))
            {
                OnWinFormShown(_inputID);
                _inputID.SetInputToolArg(args);
                _inputID.SetLocation(screenRect);
                _inputID.Show();
                _inputID.Focus();
                _isKeyboardActived = true;
            }
            // 使用手机号码输入键盘
            else if (args.DictionaryFileName.Contains("Phone")
                || args.DictionaryFileName.Contains("PostCode"))           
            {
                OnWinFormShown(_inputPhone);
                _inputPhone.SetInputToolArg(args);
                _inputPhone.SetLocation(screenRect);
                _inputPhone.Show();
                _inputPhone.Focus();
                _isKeyboardActived = true;
            }
            // 使用护照号码输入键盘
            else if (args.DictionaryFileName.Contains("Passport"))
            {
                OnWinFormShown(_inputPassport);
                _inputPassport.SetInputToolArg(args);
                _inputPassport.SetLocation(screenRect);
                _inputPassport.Show();
                _inputPassport.Focus();
                _isKeyboardActived = true;
            }
            else if (args.DictionaryFileName.Equals("Letter"))
            {
                OnWinFormShown(_letterKeyBoard);
                _letterKeyBoard.SetInputToolArg(args);
                _letterKeyBoard.SetLocation(screenRect);
                _letterKeyBoard.Show();
                _letterKeyBoard.Focus();
                _isKeyboardActived = true;
            }
            //else if (args.DictionaryFileName.Equals("NumAndCaps"))
            //{
            //    OnWinFormShown(FormInputWord);
            //    FormInputWord.SetInputToolArg(args);
            //    FormInputWord.Show();
            //    FormInputWord.Focus();
            //    _isKeyboardActived = true;
            //}
            //else if (args.DictionaryFileName.Equals("NumberCapitals"))
            //{
            //    OnWinFormShown(FormKeyboard);
            //    FormKeyboard.SetInputToolArg(args);
            //    FormKeyboard.Show();
            //    FormKeyboard.Focus();
            //    _isKeyboardActived = true;
            //}
            else if (!string.IsNullOrEmpty(args.DictionaryFileName)) // 使用字典选项选择键盘
            {
                OnWpfFormShown(_selectKeyBoard);
                
                _selectKeyBoard.SetKeyBoardArg(args);
                _selectKeyBoard.SetLocation(screenRect);
                _selectKeyBoard.Show();
                _selectKeyBoard.Focus();
                _isKeyboardActived = true;
            }
            else // 使用默认手写键盘
            {
                OnWinFormShown(_inputTool);
                _inputTool.SetInputToolArg(args);
                _inputTool.SetLocation(screenRect);
                _inputTool.Show();
                _inputTool.Focus();
                _isKeyboardActived = true;
            }
        }
    }
}
